package org.scheduler4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.scheduler4j.util.DateUtil;

/**
 * Day class, just contain Day information, without time information
 * 
 * @author Eric
 * 
 */
public class Day implements Duration {

	private Date date;

	public Day() {
		this(new Date());
	}

	public Day(Date date) {
		this.date = DateUtil.getDateWithoutTime(date);
	}

	public Day(String day) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
		try {
			this.date = format.parse(day);
		} catch (ParseException ex) {
			format = new SimpleDateFormat(Constants.DEFAULT_DAY_FORMAT);
			try {
				this.date = format.parse(day);
			} catch (ParseException e) {
				format = new SimpleDateFormat("yyyyMMdd");
				try {
					this.date = format.parse(day);
				} catch (ParseException e1) {
					throw new InvalidDayException(
							"Invalid Day format : "
									+ day
									+ ", you should give format as yyyyMMdd, yyyy-MM-dd or yyyy/MM/dd");
				}
			}
		}
	}

	public Day(int year, int month, int day) {
		this.date = DateUtil.createDate(year, month, day);
	}

	public Date toDate() {
		return date;
	}

	public int getYear() {
		return DateUtil.getYear(date);
	}

	public int getMonth() {
		return DateUtil.getMonth(date);
	}

	public int getDay() {
		return DateUtil.getDay(date);
	}

	public boolean isWeekday() {
		return DateUtil.isWeekday(date);
	}

	public boolean isBefore(Day day) {
		return date.getTime() < day.date.getTime();
	}

	public boolean isAfter(Day day) {
		return date.getTime() > day.date.getTime();
	}

	public boolean isSameDay(Day day) {
		return date.getTime() == day.date.getTime();
	}

	public Day tomorrow() {
		return new Day(DateUtil.afterDays(date, 1));
	}

	public Day after(int days) {
		return new Day(DateUtil.afterDays(date, days));
	}

	public Day before(int days) {
		return new Day(DateUtil.afterDays(date, days));
	}

	public Day yesterday() {
		return new Day(DateUtil.afterDays(date, -1));
	}

	@Override
	public String toString() {
		return new SimpleDateFormat(Constants.DEFAULT_DAY_FORMAT).format(date);
	}

	@Override
	public int hashCode() {
		return date.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof Day)) {
			return false;
		}
		Day tmp = (Day) obj;
		return getYear() == tmp.getYear() && getMonth() == tmp.getMonth()
				&& getDay() == tmp.getDay();
	}

	@Override
	public List<Day> getDays() {
		List<Day> result = new ArrayList<Day>();
		result.add(this);
		return result;
	}

}
